; 1-8
; 1
(define a 3)
(define b (+ a 1))
(+ a b (* a b))
(= a b)
(if (and (> b a) (< b (* a b)))
    b
    a)
(cond ((= a 4) 6)
    ((= b 4) (+ 6 7 a))
    (else 25)
)
(+ 2 (if (> b a) b a))
(* (+ a 1)
    (cond ((> a b) a)
        ((< a b) b)
        (else -1)
    )
)

; 2
(/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 4 3)))))
    (* 3 (- 6 2) (- 2 7)))

; 3
; find the square of two larger num out of 3 input
(define (square x)
    (* x x))
(define (square_sum x y z)
    (+ (square x) (square y) (square z)))
(define (less x y)
(if (< x y) x y))

; 4
(define (f x y z)
    (- (square_sum x y z) 
        (square (less (less x y) z)) 
    )
)
(f 4 2 100)

; 5
; testing normal or applicative.
; note that applicative try to evaluate all args before eval
; normal only do eval when needed
; if applicative, the program won't stop!
(define (p) (p)) ; infinite recursion
(define (test x y)
    (if (= x 0)
        0
        y))
; uncomment next line to test Ex1.5
; (test 0 (p))

; 6
; why we really need a "if"?
(define (new-if pred conseq alter)
    (cond (pred conseq)
        (else alter))
)
; seems good
(new-if (= 2 3) 100 1)
(define (f x)
    (new-if (> x 100) 1000 1))
(f 200)
; but cannot handle recurion situation, for applicative-order
; it will try to eval all operand, but in the "if", we will first eval predicate
; Example: Modified finding square root
(define (sqrt-iter x guess)
    (new-if (good-enough? (square guess) x)
        guess
        (sqrt-iter x (average guess (/ x guess))))
)
(define (average x y)
    (/ (+ x y) 2))
(define (good-enough? a b)
    (and (< (- a b) 0.01) (< (- b a) 0.01)) )
; uncomment the next line to test 1.6
; (sqrt-iter 4 2.5)

